home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / ubufox / chrome / ubufox.jar / content / pluginInstallerWizard.js < prev    next >
Encoding:
JavaScript  |  2009-04-14  |  29.9 KB  |  858 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Plugin Finder Service.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * IBM Corporation.
  18.  * Portions created by the IBM Corporation are Copyright (C) 2004
  19.  * IBM Corporation. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Doron Rosenberg <doronr@us.ibm.com>
  23.  *   Alexander Sack <asac@jwsdot.com> - Canonical Ltd.
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. function nsPluginInstallerWizard(){
  40.  
  41.   // create the request array
  42.   this.mPluginRequestArray = new Object();
  43.   // since the array is a hash, store the length
  44.   this.mPluginRequestArrayLength = 0;
  45.  
  46.   // create the plugin info array.
  47.   // a hash indexed by plugin id so we don't install 
  48.   // the same plugin more than once.
  49.   this.mPluginInfoArray = new Object();
  50.   this.mPluginInfoArrayLength = 0;
  51.  
  52.   this.mMimeTypePluginSelections = new Object();
  53.  
  54.   // holds plugins we couldn't find
  55.   this.mPluginNotFoundArray = new Object();
  56.   this.mPluginNotFoundArrayLength = 0;
  57.  
  58.   // array holding pids of plugins that require a license
  59.   this.mPluginLicenseArray = new Array();
  60.  
  61.   this.mPluginGroupBoxes = new Array();
  62.   this.mPluginPlaceHolder = null;
  63.  
  64.   // how many plugins are to be installed
  65.   this.pluginsToInstallNum = 0;
  66.  
  67.   this.mTab = null;
  68.   this.mBrowser = null;
  69.   this.mSuccessfullPluginInstallation = 0;
  70.  
  71.   this.mPluginPidArray = new Object();
  72.   // arguments[0] is an array that contains two items:
  73.   //     an array of mimetypes that are missing
  74.   //     a reference to the tab that needs them, so we can reload it
  75.  
  76.   if ("arguments" in window) {
  77.     for (var item in window.arguments[0].plugins){
  78.       this.mPluginRequestArray[window.arguments[0].plugins[item].mimetype] =
  79.         new nsPluginRequest(window.arguments[0].plugins[item]);
  80.  
  81.       this.mPluginRequestArrayLength++;
  82.     }
  83.  
  84.     this.mBrowser = window.arguments[0].browser; // ffox 3
  85.     this.mTab = window.arguments[0].tab; // ffox 2
  86.   }
  87.  
  88.   this.WSPluginCounter = 0;
  89.   this.licenseAcceptCounter = 0;
  90.  
  91.   this.prefBranch = null;
  92.  
  93.   this.mNeedsRestart = false;
  94. }
  95.  
  96. nsPluginInstallerWizard.prototype.getPluginData = function (){
  97.   // for each mPluginRequestArray item, call the datasource
  98.   this.WSPluginCounter = 0;
  99.  
  100.   // initiate the datasource call
  101.   var rdfUpdater = new nsRDFItemUpdater(this.getOS(), this.getChromeLocale());
  102.  
  103.   for (item in this.mPluginRequestArray) {
  104.     rdfUpdater.checkForPlugin(this.mPluginRequestArray[item]);
  105.   }
  106. }
  107.  
  108. // aPluginInfo is null if the datasource call failed, and pid is -1 if
  109. // no matching plugin was found.
  110. nsPluginInstallerWizard.prototype.pluginInfoReceived = function (aPluginInfos){
  111.   this.WSPluginCounter++;
  112.  
  113.   if (aPluginInfos ) {
  114.     // hash by id
  115.  
  116.     var resultSetMimeType = null;
  117.     var filteredPluginInfoSet = new Array();
  118.     var noResultInfo = null;
  119.     var aPluginInfo = null;
  120.     for (var i = 0; i < aPluginInfos.length; i++) {
  121.       aPluginInfo = aPluginInfos[i];
  122.       resultSetMimeType = aPluginInfo.requestedMimetype;
  123.       if (aPluginInfo && aPluginInfo.pid != -1 &&
  124.       ( aPluginInfo.XPILocation || aPluginInfo.manualInstallationURL )) {
  125.     hasResults = true;
  126.     filteredPluginInfoSet.push(aPluginInfo);
  127.     this.mPluginPidArray[aPluginInfo.pid] = aPluginInfo;
  128.       }
  129.     }
  130.  
  131.     if(filteredPluginInfoSet.length > 0)
  132.     {
  133.       this.mPluginInfoArray[resultSetMimeType] = filteredPluginInfoSet;
  134.       this.mPluginInfoArrayLength++;
  135.     } else {
  136.       this.mPluginNotFoundArray[resultSetMimeType] = filteredPluginInfoSet;
  137.       this.mPluginNotFoundArrayLength++;
  138.     }
  139.   }
  140.  
  141.   var progressMeter = document.getElementById("ws_request_progress");
  142.  
  143.   if (progressMeter.getAttribute("mode") == "undetermined")
  144.     progressMeter.setAttribute("mode", "determined");
  145.  
  146.   progressMeter.setAttribute("value",
  147.       ((this.WSPluginCounter / this.mPluginRequestArrayLength) * 100) + "%");
  148.  
  149.   if (this.WSPluginCounter == this.mPluginRequestArrayLength) {
  150.     // check if no plugins were found
  151.     if (this.mPluginInfoArrayLength == 0 && this.mPluginInfoAptArrayLength == 0) {
  152.       this.advancePage("lastpage", true, false, false);
  153.     } else {
  154.       // we want to allow user to cancel
  155.       this.advancePage(null, true, false, true);
  156.     }
  157.   } else {
  158.     // process more.
  159.   }
  160. }
  161.  
  162. nsPluginInstallerWizard.prototype.createPluginSetGroupBox = function () {
  163.  
  164.   var gbox = document.createElement("vbox");
  165.   gbox.setAttribute("flex", "1");
  166.  
  167.   var caption = document.createElement("caption");
  168.   caption.setAttribute("label", this.getString("ubufox.pluginWizard.availablePluginsPage.description.label")+" "+mimetype+":");
  169.   gbox.appendChild(caption);
  170.  
  171.   return gbox;
  172. }
  173.  
  174. function doToggleInstallPluginEvent(e) {
  175.   gPluginInstaller.toggleInstallPlugin(e);
  176. }
  177.  
  178. nsPluginInstallerWizard.prototype.showPluginList = function () {
  179.   var toReplace = null;
  180.  
  181.   if(this.mPluginGroupBoxes.length > 0)
  182.     this.mPluginGroupBoxes.pop();
  183.   
  184.   if (toReplace && this.mPluginPlaceHolder) {
  185.     toReplace.getParent().replaceChild(toReplace, 
  186.                        this.mPluginPlaceHolder);
  187.   }
  188.   
  189.   this.pluginsToInstallNum = 0;
  190.   var hasPluginWithInstallerUI = false;
  191.  
  192.   var groupBox = null;
  193.   var lastSibling = null;
  194.  
  195.   for (mimetype in this.mPluginInfoArray){
  196.     // [plugin image] [Plugin_Name Plugin_Version]
  197.     var pluginInfoSet = this.mPluginInfoArray[mimetype];
  198.     var firstPluginSet = (groupBox == null);
  199.     groupBox = this.createPluginSetGroupBox(document, mimetype, pluginInfoSet);
  200.  
  201.     if(firstPluginSet) {
  202.       this.mPluginPlaceHolder = document.getElementById("pluginselection-placeholder");
  203.       this.mPluginPlaceHolder.parentNode.replaceChild(groupBox, this.mPluginPlaceHolder);
  204.     } else {
  205.       lastSibling.parentNode.insertBefore(groupBox, lastSibling);
  206.     }
  207.     lastSibling = groupBox;
  208.     this.mPluginGroupBoxes.push(groupBox);
  209.  
  210.     var radiogroup = document.createElement("richlistbox");
  211.     radiogroup.setAttribute("flex", "1");
  212.     groupBox.appendChild(radiogroup);
  213.     radiogroup.addEventListener("select", doToggleInstallPluginEvent, false);
  214.  
  215.     // OK, lets add the "None" option first
  216.     var first = true;
  217.     for (var i = 0; i < pluginInfoSet.length; i++) {
  218.       var pluginInfo = pluginInfoSet[i];
  219.       var rli = document.createElement("richlistitem");
  220.       rli.setAttribute("style", "border-bottom: dotted 1px lightgrey; padding: 0.5em 1em 0.5em 1em");
  221.       rli._ubufoxPluginInfo = pluginInfo;
  222.       rli._ubufoxPluginInfoMimeType = mimetype;
  223.       radiogroup.appendChild(rli);
  224.  
  225.       var distributorImageWrap = document.createElement("vbox");
  226.  
  227.       var spacer = document.createElement("hbox");
  228.       spacer.setAttribute("flex", "1");
  229.       distributorImageWrap.appendChild(spacer);
  230.  
  231.       var distributorImage = document.createElement("image");
  232.       distributorImageWrap.appendChild(distributorImage);
  233.       distributorImageWrap.setAttribute("style", "vertical-align: middle");
  234.       distributorImage.setAttribute("style", "vertical-align: middle");
  235.       distributorImageWrap.setAttribute("flex", "0");
  236.       distributorImage.setAttribute("class", "distributor-image");
  237.       if(pluginInfo.XPILocation && pluginInfo.XPILocation.indexOf("apt:") == 0) {
  238.     distributorImage.setAttribute("src", "chrome://ubufox/content/ubuntulogo32.png");
  239.     pluginInfo.IconUrl = "chrome://ubufox/content/ubuntulogo32.png";
  240.       } else {
  241.     if(!pluginInfo.IconUrl || pluginInfo.IconUrl.length == 0) {
  242.       distributorImage.setAttribute("src", "chrome://ubufox/content/internet32.png");
  243.       pluginInfo.IconUrl = "chrome://ubufox/content/internet32.png";
  244.     } else {
  245.       distributorImage.setAttribute("src", pluginInfo.IconUrl);
  246.     }
  247.       } 
  248.  
  249.       spacer = document.createElement("hbox");
  250.       spacer.setAttribute("flex", "1");
  251.       distributorImageWrap.appendChild(spacer);
  252.  
  253.       rli.appendChild(distributorImageWrap);
  254.  
  255.       var nameAndDesc = document.createElement("vbox");
  256.       rli.appendChild(nameAndDesc);
  257.  
  258.       var nameLabel = document.createElement("label");
  259.       nameLabel.setAttribute("value", pluginInfo.name + " " + (pluginInfo.version ? pluginInfo.version : ""));
  260.       nameLabel.setAttribute("style", "font-weight: bold");
  261.       nameAndDesc.appendChild(nameLabel);
  262.  
  263.       var descDesc = document.createElement("description");
  264.       if (!pluginInfo.desc) {
  265.         pluginInfo.desc = this.getString("ubufox.pluginWizard.description.notfound");
  266.       }
  267.       descDesc.appendChild(document.createTextNode(pluginInfo.desc));
  268.       descDesc.setAttribute("style", "white-space: pre;");
  269.       nameAndDesc.appendChild(descDesc);
  270.     }
  271.  
  272.     radiogroup.selectedIndex = 0;
  273.  
  274.     if (pluginInfo.InstallerShowsUI == "true")
  275.       hasPluginWithInstallerUI = true;
  276.  
  277.     this.pluginsToInstallNum++;
  278.   }
  279.  
  280.   if (hasPluginWithInstallerUI)
  281.     document.getElementById("installerUI").hidden = false;
  282.  
  283.   this.canAdvance(false);
  284.   this.canRewind(false);
  285. }
  286.  
  287. nsPluginInstallerWizard.prototype.toggleInstallPlugin = function (e) {
  288.   var selectedItem = e.target.selectedItem;
  289.   var mime = selectedItem._ubufoxPluginInfoMimeType;
  290.   this.mMimeTypePluginSelections[mime] = selectedItem._ubufoxPluginInfo.pid;
  291.  
  292.   let count  = 0;
  293.   for (mime in this.mMimeTypePluginSelections) {
  294.     if(this.mMimeTypePluginSelections[mime] && this.mMimeTypePluginSelections[mime] != "-1")
  295.       count++;
  296.   }
  297.  
  298.   // if no plugins are checked, don't allow to advance
  299.   if (count > 0)
  300.     this.canAdvance(true);
  301.   else
  302.     this.canAdvance(false);
  303. }
  304.  
  305. nsPluginInstallerWizard.prototype.canAdvance = function (aBool){
  306.   document.getElementById("plugin-installer-wizard").canAdvance = aBool;
  307. }
  308.  
  309. nsPluginInstallerWizard.prototype.canRewind = function (aBool){
  310.   document.getElementById("plugin-installer-wizard").canRewind = aBool;
  311. }
  312.  
  313. nsPluginInstallerWizard.prototype.canCancel = function (aBool){
  314.   document.documentElement.getButton("cancel").disabled = !aBool;
  315. }
  316.  
  317. nsPluginInstallerWizard.prototype.showLicenses = function (){
  318.   this.canAdvance(false);
  319.   this.canRewind(false);
  320.  
  321.   // only add if a license is provided and the plugin was selected to
  322.   // be installed
  323.   for (mimetype in this.mMimeTypePluginSelections){
  324.     var pid = this.mMimeTypePluginSelections[mimetype];
  325.     var pluginInfo = this.mPluginPidArray[pid];
  326.     if (pluginInfo && pluginInfo.licenseURL && (pluginInfo.licenseURL != "")) {
  327.       this.mPluginLicenseArray.push(pluginInfo.pid);
  328.     }
  329.   }
  330.  
  331.   if (this.mPluginLicenseArray.length == 0) {
  332.     // no plugins require licenses
  333.     this.advancePage(null, true, false, false);
  334.   } else {
  335.     this.licenseAcceptCounter = 0;
  336.  
  337.     // add a nsIWebProgress listener to the license iframe.
  338.     var docShell = document.getElementById("licenseIFrame").docShell;
  339.     var iiReq = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  340.     var webProgress = iiReq.getInterface(Components.interfaces.nsIWebProgress);
  341.     webProgress.addProgressListener(gPluginInstaller.progressListener,
  342.                                     Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  343.  
  344.  
  345.     this.showLicense();
  346.   }
  347. }
  348.  
  349. nsPluginInstallerWizard.prototype.enableNext = function (){
  350.   // if only one plugin exists, don't enable the next button until
  351.   // the license is accepted
  352.   if (gPluginInstaller.pluginsToInstallNum > 1)
  353.     gPluginInstaller.canAdvance(true);
  354.  
  355.   document.getElementById("licenseRadioGroup1").disabled = false;
  356.   document.getElementById("licenseRadioGroup2").disabled = false;
  357. }
  358.  
  359. const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  360. nsPluginInstallerWizard.prototype.progressListener = {
  361.   onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  362.   {
  363.     if ((aStateFlags & nsIWebProgressListener.STATE_STOP) &&
  364.        (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK)) {
  365.       // iframe loaded
  366.       gPluginInstaller.enableNext();
  367.     }
  368.   },
  369.  
  370.   onProgressChange : function(aWebProgress, aRequest, aCurSelfProgress,
  371.                               aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
  372.   {},
  373.   onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  374.   {},
  375.  
  376.   QueryInterface : function(aIID)
  377.   {
  378.      if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  379.          aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  380.          aIID.equals(Components.interfaces.nsISupports))
  381.        return this;
  382.      throw Components.results.NS_NOINTERFACE;
  383.    }
  384. }
  385.  
  386. nsPluginInstallerWizard.prototype.showLicense = function (){
  387.   var pluginInfo = this.mPluginPidArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
  388.  
  389.   this.canAdvance(false);
  390.  
  391.   loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
  392.  
  393.   document.getElementById("licenseIFrame").webNavigation.loadURI(pluginInfo.licenseURL, loadFlags, null, null, null);
  394.  
  395.   document.getElementById("pluginLicenseLabel").firstChild.nodeValue = 
  396.     this.getFormattedString("pluginLicenseAgreement.label", [pluginInfo.name]);
  397.  
  398.   document.getElementById("licenseRadioGroup1").disabled = true;
  399.   document.getElementById("licenseRadioGroup2").disabled = true;
  400.   document.getElementById("licenseRadioGroup").selectedIndex = 
  401.     pluginInfo.licenseAccepted ? 0 : 1;
  402. }
  403.  
  404. nsPluginInstallerWizard.prototype.showNextLicense = function (){
  405.   var rv = true;
  406.  
  407.   if (this.mPluginLicenseArray.length > 0) {
  408.     this.storeLicenseRadioGroup();
  409.  
  410.     this.licenseAcceptCounter++;
  411.  
  412.     if (this.licenseAcceptCounter < this.mPluginLicenseArray.length) {
  413.       this.showLicense();
  414.  
  415.       rv = false;
  416.       this.canRewind(true);
  417.     }
  418.   }
  419.  
  420.   return rv;
  421. }
  422.  
  423. nsPluginInstallerWizard.prototype.showPreviousLicense = function (){
  424.   this.storeLicenseRadioGroup();
  425.   this.licenseAcceptCounter--;
  426.  
  427.   if (this.licenseAcceptCounter > 0)
  428.     this.canRewind(true);
  429.   else
  430.     this.canRewind(false);
  431.  
  432.   this.showLicense();
  433.   
  434.   // don't allow to return from the license screens
  435.   return false;
  436. }
  437.  
  438. nsPluginInstallerWizard.prototype.storeLicenseRadioGroup = function (){
  439.   var pluginInfo = this.mPluginPidArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
  440.   pluginInfo.licenseAccepted = !document.getElementById("licenseRadioGroup").selectedIndex;
  441. }
  442.  
  443. nsPluginInstallerWizard.prototype.licenseRadioGroupChange = function(aAccepted) {
  444.   // only if one plugin is to be installed should selection change the next button
  445.   if (this.pluginsToInstallNum == 1)
  446.     this.canAdvance(aAccepted);
  447. }
  448.  
  449. nsPluginInstallerWizard.prototype.advancePage = function (aPageId, aCanAdvance, aCanRewind, aCanCancel){
  450.   this.canAdvance(true);
  451.   document.getElementById("plugin-installer-wizard").advance(aPageId);
  452.  
  453.   this.canAdvance(aCanAdvance);
  454.   this.canRewind(aCanRewind);
  455.   this.canCancel(aCanCancel);
  456. }
  457.  
  458. nsPluginInstallerWizard.prototype.startPluginInstallation = function (){
  459.   this.canAdvance(false);
  460.   this.canRewind(false);
  461.  
  462.   // since the user can choose what plugins to install, we need to store
  463.   // which ones were choosen, as nsIXPInstallManager returns an index and not the
  464.   // mimetype.  So store the pids.
  465.  
  466.   // for ubutfox we deal with multiple cases: first case is XPIInstall, which will
  467.   // run the "normal" XPIInstall process; second case is XPIInstall url contains
  468.   // and apt: protocol url ... this will run apt protocol handler 
  469.   var pluginURLArray = new Array();
  470.   var pluginHashArray = new Array();
  471.   var pluginPidArray = new Array();
  472.   this.mAptPluginURLArray = new Array();
  473.   this.mAptPluginPidArray = new Array();
  474.  
  475.   for (mime in this.mMimeTypePluginSelections) {
  476.     var pluginPid = this.mMimeTypePluginSelections[mime];
  477.     var pluginItem = this.mPluginPidArray[pluginPid];
  478.  
  479.     // only push to the array if it has an XPILocation, else nsIXPInstallManager
  480.     // will complain.
  481.     if (pluginItem && pluginItem.XPILocation && pluginItem.XPILocation.indexOf("apt:") != 0 && pluginItem.licenseAccepted) {
  482.       pluginURLArray.push(pluginItem.XPILocation);
  483.       pluginHashArray.push(pluginItem.XPIHash);
  484.       pluginPidArray.push(pluginItem.pid);
  485.     } else if (pluginItem && pluginItem.XPILocation && pluginItem.XPILocation.indexOf("apt:") == 0) {
  486.       this.mAptPluginURLArray.push(pluginItem.XPILocation);
  487.       this.mAptPluginPidArray.push(pluginPid);
  488.     } else {
  489.       window.alert("Unhandled mime install flavour (supported: vendor, apt)");
  490.       continue;
  491.     }
  492.   }
  493.  
  494.   if (pluginURLArray.length > 0)
  495.     PluginXPIInstallService.startPluginInstallation(pluginURLArray,
  496.                             pluginHashArray,
  497.                             pluginPidArray);
  498.   else if (this.mAptPluginURLArray.length > 0)
  499.     PluginAPTInstallService.startPluginInstallation(this.mAptPluginURLArray,
  500.                             this.mAptPluginPidArray);
  501.   else
  502.     this.advancePage(null, true, false, false);
  503. }
  504.  
  505. /*
  506.   0    starting download
  507.   1    download finished
  508.   2    starting installation
  509.   3    finished installation
  510.   4    all done
  511. */
  512. nsPluginInstallerWizard.prototype.pluginXPIInstallationProgress = function (aPid, aProgress, aError) {
  513.  
  514.   var statMsg = null;
  515.   var pluginInfo = null;
  516.  
  517.   if(aPid)
  518.     pluginInfo = gPluginInstaller.mPluginPidArray[aPid];
  519.  
  520.   switch (aProgress) {
  521.  
  522.     case 0:
  523.       statMsg = this.getFormattedString("pluginInstallation.download.start", [pluginInfo.name]);
  524.       break;
  525.  
  526.     case 1:
  527.       statMsg = this.getFormattedString("pluginInstallation.download.finish", [pluginInfo.name]);
  528.       break;
  529.  
  530.     case 2:
  531.       statMsg = this.getFormattedString("pluginInstallation.install.start", [pluginInfo.name]);
  532.       break;
  533.     case 6:
  534.       statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.start", [pluginInfo.name]);
  535.       break;
  536.     case 3:
  537.       if (aError) {
  538.         statMsg = this.getFormattedString("pluginInstallation.install.error", [pluginInfo.name, aError]);
  539.         pluginInfo.error = aError;
  540.       } else {
  541.         statMsg = this.getFormattedString("pluginInstallation.install.finish", [pluginInfo.name]);
  542.         pluginInfo.error = null;
  543.       }
  544.       break;
  545.  
  546.     case 7:
  547.       if (aError) {
  548.         statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.error", [pluginInfo.name, aError]);
  549.         pluginInfo.error = aError;
  550.       } else {
  551.         statMsg = "APT - " + this.getFormattedString("pluginInstallation.install.finish", [pluginInfo.name]);
  552.         pluginInfo.error = null;
  553.       }
  554.       break;
  555.  
  556.     case 4:
  557.       PluginAPTInstallService.startPluginInstallation(this.mAptPluginURLArray,
  558.                               this.mAptPluginPidArray);
  559.       break;
  560.     case 8:
  561.       this.advancePage(null, true, false, false);
  562.       statMsg = this.getString("pluginInstallation.complete");
  563.       break;
  564.     default:
  565.       window.alert("unexpected error during plugin install [code=1001]");
  566.       break;
  567.   }
  568.  
  569.   if (statMsg)
  570.     document.getElementById("plugin_install_progress_message").value = statMsg;
  571. }
  572.  
  573. nsPluginInstallerWizard.prototype.pluginInstallationProgressMeter = function (aPid, aValue, aMaxValue){
  574.   var progressElm = document.getElementById("plugin_install_progress");
  575.  
  576.   if (progressElm.getAttribute("mode") == "undetermined")
  577.     progressElm.setAttribute("mode", "determined");
  578.   
  579.   progressElm.setAttribute("value", Math.ceil((aValue / aMaxValue) * 100) + "%")
  580. }
  581.  
  582. nsPluginInstallerWizard.prototype.addPluginResultRow = function (aImgSrc, aName, aNameTooltip, aStatus, aStatusTooltip, aManualUrl){
  583.   var myRows = document.getElementById("pluginResultList");
  584.  
  585.   var myRow = document.createElement("row");
  586.   myRow.setAttribute("align", "center");
  587.  
  588.   // create the image
  589.   var myImage = document.createElement("image");
  590.   myImage.setAttribute("src", aImgSrc);
  591.   myImage.setAttribute("height", "16px");
  592.   myImage.setAttribute("width", "16px");
  593.   myRow.appendChild(myImage)
  594.  
  595.   // create the labels
  596.   var myLabel = document.createElement("label");
  597.   myLabel.setAttribute("value", aName);
  598.   if (aNameTooltip)
  599.     myLabel.setAttribute("tooltiptext", aNameTooltip);
  600.   myRow.appendChild(myLabel);
  601.  
  602.   if (aStatus) {
  603.     myLabel = document.createElement("label");
  604.     myLabel.setAttribute("value", aStatus);
  605.     myRow.appendChild(myLabel);
  606.   }
  607.  
  608.   // manual install
  609.   if (aManualUrl) {
  610.     var myButton = document.createElement("button");
  611.  
  612.     var manualInstallLabel = this.getString("pluginInstallationSummary.manualInstall.label");
  613.     var manualInstallTooltip = this.getString("pluginInstallationSummary.manualInstall.tooltip");
  614.  
  615.     myButton.setAttribute("label", manualInstallLabel);
  616.     myButton.setAttribute("tooltiptext", manualInstallTooltip);
  617.  
  618.     myRow.appendChild(myButton);
  619.  
  620.     // XXX: XUL sucks, need to add the listener after it got added into the document
  621.     if (aManualUrl)
  622.       myButton.addEventListener("command", function() { gPluginInstaller.loadURL(aManualUrl) }, false);
  623.   }
  624.  
  625.   myRows.appendChild(myRow);
  626. }
  627.  
  628. nsPluginInstallerWizard.prototype.showPluginResults = function (){
  629.   var notInstalledList = "?action=missingplugins";
  630.   var myRows = document.getElementById("pluginResultList");
  631.  
  632.   this.mNeedsRestart = false;
  633.  
  634.   // clear children
  635.   for (var run = myRows.childNodes.length; run--; run > 0)
  636.     myRows.removeChild(myRows.childNodes.item(run));
  637.  
  638.   for (mimetype in this.mMimeTypePluginSelections) {
  639.     var pid = this.mMimeTypePluginSelections[mimetype];
  640.     var pluginInfoItem = this.mPluginPidArray[pid];
  641.     // [plugin image] [Plugin_Name Plugin_Version] [Success/Failed] [Manual Install (if Failed)]
  642.  
  643.     var myPluginItem = pluginInfoItem; //this.mPluginInfoArray[pluginInfoItem];
  644.  
  645.     var statusMsg;
  646.     var statusTooltip;
  647.     if (myPluginItem.error){
  648.       statusMsg = this.getString("pluginInstallationSummary.failed");
  649.       statusTooltip = myPluginItem.error;
  650.       notInstalledList += "&mimetype=" + pluginInfoItem;
  651.     } else if (myPluginItem.licenseURL && !myPluginItem.licenseAccepted) {
  652.       statusMsg = this.getString("pluginInstallationSummary.licenseNotAccepted");
  653.     } else if (!myPluginItem.XPILocation) {
  654.       statusMsg = this.getString("pluginInstallationSummary.notAvailable");
  655.       notInstalledList += "&mimetype=" + pluginInfoItem;
  656.     } else {
  657.       this.mSuccessfullPluginInstallation++;
  658.       statusMsg = this.getString("pluginInstallationSummary.success");
  659.  
  660.       // only check needsRestart if the plugin was successfully installed.
  661.       if (myPluginItem.needsRestart)
  662.     this.mNeedsRestart = false;
  663.     }
  664.  
  665.     // manual url - either returned from the webservice or the pluginspage attribute
  666.     var manualUrl;
  667.     if ((myPluginItem.error || !myPluginItem.XPILocation) && (myPluginItem.manualInstallationURL || this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage)){
  668.       manualUrl = myPluginItem.manualInstallationURL ? myPluginItem.manualInstallationURL : this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage;
  669.     }
  670.  
  671.     this.addPluginResultRow(
  672.                 myPluginItem.IconUrl, 
  673.                 myPluginItem.name + " " + (myPluginItem.version ? myPluginItem.version : ""),
  674.                 null,
  675.                 statusMsg, 
  676.                 statusTooltip,
  677.                 manualUrl);
  678.   }
  679.  
  680.   // handle plugins we couldn't find
  681.   for (pluginInfoItem in this.mPluginNotFoundArray){
  682.     var pluginRequest = this.mPluginRequestArray[pluginInfoItem];
  683.  
  684.     // if there is a pluginspage, show UI
  685.     if (pluginRequest) {
  686.       this.addPluginResultRow(
  687.           "",
  688.           this.getFormattedString("pluginInstallation.unknownPlugin", [pluginInfoItem]),
  689.           null,
  690.           null,
  691.           null,
  692.           pluginRequest.pluginsPage);
  693.     }
  694.  
  695.     notInstalledList += "&mimetype=" + pluginInfoItem;
  696.   }
  697.  
  698.   // no plugins were found, so change the description of the final page.
  699.   if (this.mPluginInfoArrayLength == 0) {
  700.     var noPluginsFound = this.getString("pluginInstallation.noPluginsFound");
  701.     document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsFound);
  702.   } else if (this.mSuccessfullPluginInstallation == 0) {
  703.     // plugins found, but none were installed.
  704.     var noPluginsInstalled = this.getString("pluginInstallation.noPluginsInstalled");
  705.     document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsInstalled);
  706.   }
  707.  
  708.   document.getElementById("pluginSummaryRestartNeeded").hidden = !this.mNeedsRestart;
  709.  
  710.   var app = Components.classes["@mozilla.org/xre/app-info;1"]
  711.                       .getService(Components.interfaces.nsIXULAppInfo);
  712.  
  713.   // set the get more info link to contain the mimetypes we couldn't install.
  714.   notInstalledList +=
  715.     "&appID=" + app.ID +
  716.     "&appVersion=" + app.platformBuildID +
  717.     "&clientOS=" + this.getOS() +
  718.     "&chromeLocale=" + this.getChromeLocale();
  719.  
  720.   document.getElementById("moreInfoLink").addEventListener("click", function() { gPluginInstaller.loadURL("https://pfs.mozilla.org/plugins/" + notInstalledList) }, false);
  721.  
  722.   this.canAdvance(true);
  723.   this.canRewind(false);
  724.   this.canCancel(false);
  725. }
  726.  
  727. nsPluginInstallerWizard.prototype.loadURL = function (aUrl){
  728.   // Check if the page where the plugin came from can load aUrl before
  729.   // loading it, and do *not* allow loading javascript: or data: URIs.
  730.   var pluginPage = window.opener.content.location.href;
  731.  
  732.   const nsIScriptSecurityManager =
  733.     Components.interfaces.nsIScriptSecurityManager;
  734.   var secMan =
  735.     Components.classes["@mozilla.org/scriptsecuritymanager;1"]
  736.     .getService(nsIScriptSecurityManager);
  737.  
  738.   secMan.checkLoadURIStr(pluginPage, aUrl,
  739.                          nsIScriptSecurityManager.DISALLOW_SCRIPT_OR_DATA);
  740.  
  741.   window.opener.open(aUrl);
  742. }
  743.  
  744. nsPluginInstallerWizard.prototype.getString = function (aName){
  745.   var result;
  746.   try {
  747.     result = document.getElementById("pluginWizardString").getString(aName);
  748.   }
  749.   catch (e) {
  750.     result = document.getElementById("ubufoxPluginWizardString").getString(aName);
  751.   }
  752.   return result;
  753. }
  754.  
  755. nsPluginInstallerWizard.prototype.getFormattedString = function (aName, aArray){
  756.   var result;
  757.   try {
  758.     result = document.getElementById("pluginWizardString").getFormattedString(aName, aArray);
  759.   }
  760.   catch (e) {
  761.     result = document.getElementById("ubufoxPluginWizardString").getFormattedString(aName, aArray);
  762.   }
  763.   return result;
  764. }
  765.  
  766. nsPluginInstallerWizard.prototype.getOS = function (){
  767.   var httpService = Components.classes["@mozilla.org/network/protocol;1?name=http"]
  768.                               .getService(Components.interfaces.nsIHttpProtocolHandler);
  769.   return httpService.oscpu;
  770. }
  771.  
  772. nsPluginInstallerWizard.prototype.getChromeLocale = function (){
  773.   var chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
  774.                             .getService(Components.interfaces.nsIXULChromeRegistry);
  775.   return chromeReg.getSelectedLocale("global");
  776. }
  777.  
  778. nsPluginInstallerWizard.prototype.getPrefBranch = function (){
  779.   if (!this.prefBranch)
  780.     this.prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
  781.                                 .getService(Components.interfaces.nsIPrefBranch);
  782.   return this.prefBranch;
  783. }
  784. function nsPluginRequest(aPlugRequest){
  785.   this.mimetype = encodeURI(aPlugRequest.mimetype);
  786.   this.pluginsPage = aPlugRequest.pluginsPage;
  787. }
  788.  
  789. function PluginInfo(aResult) {
  790.   this.name = aResult.name;
  791.   this.pid = aResult.pid;
  792.   this.version = aResult.version;
  793.   this.IconUrl = aResult.IconUrl;
  794.   this.XPILocation = aResult.XPILocation;
  795.   this.XPIHash = aResult.XPIHash;
  796.   this.InstallerShowsUI = aResult.InstallerShowsUI;
  797.   this.manualInstallationURL = aResult.manualInstallationURL;
  798.   this.requestedMimetype = aResult.requestedMimetype;
  799.   this.licenseURL = aResult.licenseURL;
  800.   this.needsRestart = (aResult.needsRestart == "true");
  801.  
  802.   this.error = null;
  803.   this.toBeInstalled = true;
  804.  
  805.   // no license provided, make it accepted
  806.   this.licenseAccepted = this.licenseURL ? false : true;
  807. }
  808.  
  809. var gPluginInstaller;
  810.  
  811. function wizardInit(){
  812.   gPluginInstaller = new nsPluginInstallerWizard();
  813.   gPluginInstaller.canAdvance(false);
  814.   gPluginInstaller.getPluginData();
  815. }
  816.  
  817. function wizardFinish(){
  818.   // we restart if we have no choice ...
  819.   if (gPluginInstaller.mNeedsRestart) {
  820.     // Notify all windows that an application quit has been requested.
  821.     var os = Components.classes["@mozilla.org/observer-service;1"]
  822.                        .getService(Components.interfaces.nsIObserverService);
  823.     var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
  824.                                .createInstance(Components.interfaces.nsISupportsPRBool);
  825.     os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
  826.  
  827.     // Something aborted the quit process.
  828.     if (!cancelQuit.data) {
  829.       var nsIAppStartup = Components.interfaces.nsIAppStartup;
  830.       var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
  831.                                  .getService(nsIAppStartup);
  832.       appStartup.quit(nsIAppStartup.eAttemptQuit | nsIAppStartup.eRestart);
  833.       return true;
  834.     }
  835.   }
  836.  
  837.   if (gPluginInstaller.mBrowser) { // ffox 3 code can autoscan ...
  838.     // always refresh
  839.     var event = document.createEvent("Events");
  840.     event.initEvent("NewPluginInstalled", true, true);
  841.     var dispatched = gPluginInstaller.mBrowser.dispatchEvent(event);
  842.   }
  843.   else if (gPluginInstaller.mTab) { // ffox 2 code can autoscan ...
  844.     if ((gPluginInstaller.mSuccessfullPluginInstallation > 0) &&
  845.        (gPluginInstaller.mPluginInfoArrayLength != 0)) {
  846.       // clear the tab's plugin list only if we installed at least one plugin
  847.       gPluginInstaller.mTab.missingPlugins = null;
  848.       // reset UI
  849.       window.opener.gMissingPluginInstaller.closeNotification();
  850.       // reload the browser to make the new plugin show
  851.       window.opener.getBrowser().reloadTab(gPluginInstaller.mTab);
  852.     }
  853.   }
  854.  
  855.   return true;
  856. }
  857.  
  858.